#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QString>
#include <QMessageBox>
#include <QTextCodec>
#include <QStringList>
#include <random>
#include <QDebug>
#include <ctime>
#include <QTime>
const QString Suffix = ".txt";
static std::default_random_engine e(time(0));
static std::uniform_int_distribution<int> u(0, INT_MAX);
#define x(a) #a

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),lvl(Level::one)
{
    //QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
    file = new QFile(this);
    uptext = new StartUpdataText(this);
    init();
    //setEnabled(false);
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::ReadFileData(QList<std::string> &list, QString FileName)
{
    file->setFileName(FileName);

    if(!file->open(QFile::OpenModeFlag::ReadOnly))
    {
        //文件打开失败
        QMessageBox::question(this, tr("文件错误"), tr("%1 打开失败...").arg(file->fileName()));
        return;
    }

    QTextStream in(file);
    while(!in.atEnd())
    {
        std::string strName = std::move(in.readLine().toStdString());
        list.push_back(std::move(strName));
    }
    file->close();
}

void MainWindow::Go()
{
    if(uptext->isRunning())
        return;
    //抽奖
    bool bExit = true;

    while(bExit)
    {
        //幸运奖20个  一等奖一个 二等奖俩个  三等奖三个
        int nSize = mMap_SucessMan.count(lvl);//获取当前奖项中奖人数
        pListObj = nullptr;
        //直到产生结果
        switch(lvl)
        {
        case one:
            if(nSize >= static_cast<int> (one))//当前奖项获得人数超过设定人数
                return;//直接退出
            pListObj = &strlist_one;
            break;
        case two:
            if(nSize >= static_cast<int> (two))
                return;//直接退出
            pListObj = &strlist_two;
            break;
        case three:
            if(nSize >= static_cast<int> (three))
                return;//直接退出
            pListObj = &strlist_three;
            break;
        case lucky:
            if(nSize >= static_cast<int> (lucky))
                return;//直接退出
            pListObj = &strlist_lucky;
            break;
        }

        std::random_shuffle(pListObj->begin(), pListObj->end());//进行随机的逼格调序
        int nResult = u(e) % pListObj->size();
        qDebug() << nResult << " ";
        result_iter = pListObj->begin();
        result_iter += nResult;
        //while(nResult--)
            //++result_iter;
        if(result_iter == pListObj->end())//这里估计永远不会被触发...
            continue;

        mMap_SucessMan.insert( {lvl, *result_iter} );//插入数据
        QString num = QString::number((long)lvl);
        qDebug() << num << " " << QString((*result_iter).c_str());
        uptext->SetVarable(pListObj, result_iter);
        uptext->start();
        //ui->label->moveToThread(uptext);
//        emit SendNewItem(lvl);//发送新项目
        //check sucess-table value...
        bExit = false;//正常结束环循,这里为了以后设计一次性选出所有奖项保留
    }
}

void MainWindow::GetUpdataTextMessage(QString qstr, bool s)
{
    ui->label->setText(qstr);
    if(!s)
    {
        if(pListObj)
            pListObj->erase(result_iter);//删除这个人保证再次随机当前奖项不会参于
        //ui->label->moveToThread(this->thread());

        uptext->wait();
        uptext->quit();
        emit SendNewItem(lvl);//发送新项目
    }
}

void MainWindow::init()
{
    //读取外部名单
    ReadFileData(strlist_one, tr("%1%2").arg(reward_one).arg(Suffix));
    ReadFileData(strlist_two, tr("%1%2").arg(reward_two).arg(Suffix));
    ReadFileData(strlist_three, tr("%1%2").arg(reward_three).arg(Suffix));
    ReadFileData(strlist_lucky, tr("%1%2").arg(reward_lucky).arg(Suffix));
    //唯一性
    std::unique(strlist_one.begin(), strlist_one.end());
    std::unique(strlist_two.begin(), strlist_two.end());
    std::unique(strlist_three.begin(), strlist_three.end());
    std::unique(strlist_lucky.begin(), strlist_lucky.end());

    connect(this, SIGNAL(SendNewItem(Level)), this, SLOT(UpdataTableItem(Level)));
    connect(uptext, SIGNAL(SendUpdataText(QString,bool)), this,SLOT(GetUpdataTextMessage(QString,bool)));
}

void MainWindow::UpdataTableItem(Level l)
{
    ui->listWidget->clear();

    std::pair<m_mIterator, m_mIterator>
            result_pair = mMap_SucessMan.equal_range(l);

    while(result_pair.first != result_pair.second)
    {
        m_mIterator iter = result_pair.first;
        ui->listWidget->addItem(QString((*iter).second.c_str()));
        ++result_pair.first;
    }

}

void MainWindow::on_comboBox_currentTextChanged(const QString &arg1)
{
    if(arg1.isEmpty())
        return;

    if(uptext->isRunning())
        return;

    if(arg1 == reward_one)
        {
            lvl = one;
            qDebug() << "one\n";
        }
    else if(arg1 == reward_two)
        {
            lvl = two;
            qDebug() << "two\n";
        }
    else
        if(arg1 == reward_three)
            {
                lvl = three;
                qDebug() << "three\n";
            }
    else
            if(arg1 == reward_lucky)
            {
                lvl = lucky;
                qDebug() << "lucky\n";
            }

    ui->label->setText(QString());

    emit SendNewItem(lvl);//发送新项目
}

void MainWindow::on_pushButton_clicked()
{
    Go();
}

void MainWindow::on_pushButton_2_clicked()
{
    file->setFileName(tr("获奖名次.txt"));

    if(!file->open(QFile::OpenModeFlag::WriteOnly))
    {
        QMessageBox::question(this, tr("文件错误"), tr("写入文件 %1错误!").arg(file->fileName()));
        return;
    }

    QTextStream in(file);
    WriteResult(in, one);
    file->write("\n");
    WriteResult(in, two);
    file->write("\n");
    WriteResult(in, three);
    file->write("\n");
    WriteResult(in, lucky);
    file->write("\n");

    file->close();
}

void MainWindow::WriteResult(QTextStream &in, Level l)
{
    std::pair<m_mIterator, m_mIterator>
            result_pair = mMap_SucessMan.equal_range(l);
    while(result_pair.first != result_pair.second)
    {
        m_mIterator iter = result_pair.first++;
        in << tr("一等奖：") << tr(iter->second.c_str());
    }
}
